package OpenToday.GUI;

import OpenToday.IManager;
import java.io.IOException;
import java.util.Vector;
import OpenToday.Configuration.OpenTodayConfiguration;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

/*
 * MainGUI.java
 *
 * Created on 5  2007, 08:36
 *Note: This source code is protected under the This software is licensed under the CC-GNU GPL.
 */

/**
 *
 * @author Menny Even Danan (c) 2007. Note: This source code is protected under the This software is licensed under the CC-GNU GPL.
 */
public class MainCanvas extends Canvas implements IOpenTodayGUI {

    private class RowData {

        public final String Text;

        public RowData(String text) {
            Text = text;
        }
    }

    private class DayRow extends RowData {

        public DayRow(String dayTitle) {
            super(dayTitle);
        }
    }

    private class EventRow extends RowData {

        public final boolean AllDayEvent;

        public EventRow(String eventTitle, boolean allDayEvent) {
            super(eventTitle);
            AllDayEvent = allDayEvent;
        }
    }

    private class TodoRow extends RowData {

        public final boolean OverDue;
        public final boolean Completed;

        public TodoRow(String eventTitle, boolean overDue, boolean completed) {
            super(eventTitle);
            OverDue = overDue;
            Completed = completed;
        }
    }
    private final Image IMAGE_EVENT;
    private final Image IMAGE_NEED_TODO;
    private final Image IMAGE_HAVE_DONE_TODO;
    private final Image IMAGE_FORGOT_TODO;
    private Image IMAGE_EMPTY;
    private Font dayFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_SMALL);
    private Font eventFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_SMALL);
    private int m_firstLineOffset;
    //these three must me remembered so, i'll know when to rebuild the placeholder
    private int[] m_BackgroundRGB = new int[]{0, 0, 70};
    private final IManager m_manager;
    private final Vector m_GUIrows;
    //private final Vector m_beforeGUIrows;

    /** Creates a new instance of MainCanvas */
    public MainCanvas(IManager manager) throws IOException {
        m_manager = manager;
        IMAGE_EVENT = Image.createImage("/Event.PNG");
        IMAGE_NEED_TODO = Image.createImage("/NeedToDo.PNG");
        IMAGE_HAVE_DONE_TODO = Image.createImage("/HaveDoneToDo.PNG");
        IMAGE_FORGOT_TODO = Image.createImage("/ForgotToDo.PNG");
        super.setTitle(null);
        m_firstLineOffset = 0;
        m_GUIrows = new Vector();
        //m_beforeGUIrows = new Vector();
        FillPlaceholder();
    }

    public void RepaintRequired() {
        super.repaint();
    }

    protected void paint(Graphics g) {
        OpenTodayConfiguration cnf = OpenTodayConfiguration.getInstance();
        int y = cnf.get_ScreenTopOffset();
        //SetBackgroundColor();
        m_BackgroundRGB = cnf.get_DisplayBackgroundRGB();
        FillPlaceholder();
        g.setColor(m_BackgroundRGB[0], m_BackgroundRGB[1], m_BackgroundRGB[2]);
        g.fillRect(0, 0, getWidth(), getHeight());

        int[] dayRGB = cnf.get_DisplayDayTextRGB();
        int[] eventRGB = cnf.get_DisplayEventTextRGB();

        dayFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, cnf.getTitleFontSize());
        eventFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, cnf.getEventFontSize());

        //System.out.println("Listing events. Rows:" + m_GUIrows.size());
        for (int rowIndex = 0; rowIndex < m_GUIrows.size(); rowIndex++) {
            RowData oRow = (RowData) m_GUIrows.elementAt(rowIndex);
            y = DrawRow(g, y, oRow, dayRGB, eventRGB);
        }
    }

    public void Clear() {
        m_GUIrows.removeAllElements();
    }

    public void SetFirstLineOffset(int offset) {
        m_firstLineOffset = offset;
    }

    public void AddDayLine(String dayString) {
        m_GUIrows.addElement(new DayRow(dayString));
    }

    private void InternalAddEventLine(String eventString, boolean allDayEvent) {
        m_GUIrows.addElement(new EventRow(eventString, allDayEvent));
    }

    private String ConvertToCharValue(String value) {
        try {
            String newValue = "";
            for (int i = 0; i < value.getBytes("UNICODE").length; i++) {
                newValue += ((int) value.charAt(i));
            }

            return newValue;
        } catch (Exception e) {
            return value;
        }
    }

    public void AddLine(String text) {
        text = RTLFix(text);
        m_GUIrows.addElement(new RowData(text));
    }

    public void AddEventLine(boolean currentEvent, String eventTime, String eventString) {
        eventString = RTLFix(eventString);
        InternalAddEventLine((currentEvent ? ">" : "") + eventTime + "-" + eventString, false);
    }

    public void AddEventLine(boolean currentEvent, String startTime, String endTime, String eventString) {
    }

    public void AddAllDayEventLine(String eventString) {
        eventString = RTLFix(eventString);
        InternalAddEventLine(eventString, true);
    }

    public void AddToDoLine(boolean overdue, boolean completed, String todoString) {
        todoString = RTLFix(todoString);
        m_GUIrows.addElement(new TodoRow(todoString, overdue, completed));
    }

    public Displayable getDisplayable() {
        return this;
    }

    private static String RTLFix(String eventString) {
        //System.out.println("RTLFix called:" + eventString);
        byte[] bytes;
        try {
            bytes = eventString.getBytes("UTF8");
        //System.out.println("RTLFix UTF8");
        } catch (Exception ex) {
            System.out.println("RTLFix other! " + ex.getMessage());
            bytes = eventString.getBytes();
        }

        for (int i = 0; i < bytes.length; i += 2)//two chars jump
        {
            //System.out.println("RTLFix byte " + ((int) bytes[i]));

            if ((bytes[i] == -41))//-41: Hebrew characters
            {
                //System.out.println("RTLFix REVERSING!");
                return ReverseString(eventString);
            }
        }
        //System.out.println("RTLFix NOT RTL");
        return eventString;
    }

    private static String ReverseString(String eventString) {
        System.out.println("ReverseString start " + eventString);
        String reversed = "";
        for (int i = eventString.length() - 1; i >= 0; i--) {
            reversed += eventString.charAt(i);
        }
        System.out.println("ReverseString end " + reversed);
        return reversed;
    }

    private void SetBackgroundColor() {
        OpenTodayConfiguration cnf = OpenTodayConfiguration.getInstance();
        int[] RGB = cnf.get_DisplayBackgroundRGB();
        if ((m_BackgroundRGB[0] != RGB[0]) ||
                (m_BackgroundRGB[1] != RGB[1]) ||
                (m_BackgroundRGB[2] != RGB[2])) {
            m_BackgroundRGB = RGB;
            FillPlaceholder();
        }
    }

    private void FillPlaceholder() {
        int[] transperantEmptyEventPlaceholder = new int[16 * 16];
        for (int i = 0; i < transperantEmptyEventPlaceholder.length; i++) {
            transperantEmptyEventPlaceholder[i] = 0;
        }

        IMAGE_EMPTY = Image.createRGBImage(transperantEmptyEventPlaceholder, 16, 16, true);
    }

    private int DrawRow(Graphics g, int y, RowData oRow, int[] dayRGB, int[] eventRGB) {
        try {
            //default behaviour
            String text = oRow.Text;
            Font font = eventFont;
            g.setColor(eventRGB[0], eventRGB[1], eventRGB[2]);
            Image img = null;
            //specific stuff
            if (oRow instanceof DayRow) {
                DayRow row = (DayRow) oRow;
                g.setColor(dayRGB[0], dayRGB[1], dayRGB[2]);
                font = dayFont;
                img = null;
            } else if (oRow instanceof EventRow) {
                EventRow row = (EventRow) oRow;
                g.setColor(eventRGB[0], eventRGB[1], eventRGB[2]);
                font = eventFont;
                if (row.AllDayEvent) {
                    img = IMAGE_EMPTY;
                } else {
                    img = IMAGE_EVENT;
                }
            } else if (oRow instanceof TodoRow) {
                TodoRow row = (TodoRow) oRow;
                g.setColor(eventRGB[0], eventRGB[1], eventRGB[2]);
                font = eventFont;
                if (row.OverDue) {
                    img = IMAGE_FORGOT_TODO;
                } else if (row.Completed) {
                    img = IMAGE_HAVE_DONE_TODO;
                } else {
                    img = IMAGE_NEED_TODO;
                }
            }

            int x = 1;
            if (img != null) {
                g.drawImage(img, x, y, Graphics.TOP | Graphics.LEFT);
                x += img.getWidth() + 1;
            }
            g.setFont(font);
            g.drawString(text, x, y, Graphics.TOP | Graphics.LEFT);
            y += font.getHeight() + 1;
        } catch (Exception e) {
            System.err.println(e.getMessage());
            e.printStackTrace();
            m_manager.OnError("While painting the Today Screen:\n\r" + e.getMessage() + "\n\r" + e.toString());
        }
        return y;
    }
}
